/*
 * @Author: miteng 973203639@qq.com
 * @Date: 2023-12-21 09:19:21
 * @LastEditors: miteng 973203639@qq.com
 * @LastEditTime: 2024-07-16 15:41:52
 * @Description: 
 * Copyright (c) 2024-present HBIS Digital Technology Co.,Ltd. All rights reserved. 
 */
/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele: HTMLElement, cls: string): boolean {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele: HTMLElement, cls: string): void {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls;
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele: HTMLElement, cls: string): void {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
  }
}

export function isNumberStr(str: string): boolean {
  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}

export const exportDefault = 'export default '

export function makeMap(str: string, expectsLowerCase: boolean): (val: string) => void {
  const map = Object.create(null)
  const list = str.split(',')
  for (let i = 0; i < list.length; i++) {
    map[list[i]] = true
  }
  return expectsLowerCase
    ? (val: string): void => map[val.toLowerCase()]
    : (val: string): void => map[val]
}

export function mix(color1: string, color2: string, weight: number): string {
  weight = Math.max(Math.min(Number(weight), 1), 0);
  const r1 = parseInt(color1.substring(1, 3), 16);
  const g1 = parseInt(color1.substring(3, 5), 16);
  const b1 = parseInt(color1.substring(5, 7), 16);
  const r2 = parseInt(color2.substring(1, 3), 16);
  const g2 = parseInt(color2.substring(3, 5), 16);
  const b2 = parseInt(color2.substring(5, 7), 16);
  const r = Math.round(r1 * (1 - weight) + r2 * weight);
  const g = Math.round(g1 * (1 - weight) + g2 * weight);
  const b = Math.round(b1 * (1 - weight) + b2 * weight);
  const rStr = ('0' + (r || 0).toString(16)).slice(-2);
  const gStr = ('0' + (g || 0).toString(16)).slice(-2);
  const bStr = ('0' + (b || 0).toString(16)).slice(-2);
  return '#' + rStr + gStr + bStr;
}
// 大驼峰法
export function upperCamelCase(str: string): string {
  return str.replace(/(^.)|\_([a-zA-Z])/g, function (a, x1, y1) {
    return (x1 || y1).toLocaleUpperCase()
  })
}
// 去除第一个数组并驼峰
export function toCamal(str: string): string {
  const index = str.indexOf('_')
  const result = str.substr(index + 1, str.length)
  const strarr = result.split('_') // 将字符串用 "-" 切割为数组
  strarr[0] = strarr[0].toLowerCase() // 将数组的第一个元素转为小写
  for (let i = 1; i < strarr.length; i++) { // 从第二个元素开始循环遍历数组的长度
    // 数组i下标为0的第一个字母转为大写，其他子串改为小写
    strarr[i] = strarr[i][0].toUpperCase() + strarr[i].substring(1).toLowerCase()
  }
  return strarr.join('') // 返回数组用join链接为字符串
}
export const beautifierConf = {
  html: {
    indent_size: '2',
    indent_char: ' ',
    max_preserve_newlines: '-1',
    preserve_newlines: false,
    keep_array_indentation: false,
    break_chained_methods: false,
    indent_scripts: 'separate',
    brace_style: 'end-expand',
    space_before_conditional: true,
    unescape_strings: false,
    jslint_happy: false,
    end_with_newline: true,
    wrap_line_length: '110',
    indent_inner_html: true,
    comma_first: false,
    e4x: true,
    indent_empty_lines: true
  },
  js: {
    indent_size: '2',
    indent_char: ' ',
    max_preserve_newlines: '-1',
    preserve_newlines: false,
    keep_array_indentation: false,
    break_chained_methods: false,
    indent_scripts: 'normal',
    brace_style: 'end-expand',
    space_before_conditional: true,
    unescape_strings: false,
    jslint_happy: true,
    end_with_newline: true,
    wrap_line_length: '110',
    indent_inner_html: true,
    comma_first: false,
    e4x: true,
    indent_empty_lines: true
  }
}
// 首字母大小
export function titleCase(str: string): string {
  return str.replace(/( |^)[a-z]/g, (L) => L.toUpperCase())
}
// 深拷贝对象
// eslint-disable-next-line complexity, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
export function deepClone(obj: any): Record<string, string> | [] | RegExp | Date {
  const _toString = Object.prototype.toString

  // null, undefined, non-object, function
  if (!obj || typeof obj !== 'object') {
    return obj
  }

  // DOM Node
  if (obj.nodeType && 'cloneNode' in obj) {
    return obj.cloneNode(true)
  }

  // Date
  if (_toString.call(obj) === '[object Date]') {
    return new Date(obj.getTime())
  }

  // RegExp
  if (_toString.call(obj) === '[object RegExp]') {
    const flags = []
    if (obj.global) { flags.push('g') }
    if (obj.multiline) { flags.push('m') }
    if (obj.ignoreCase) { flags.push('i') }

    return new RegExp(obj.source, flags.join(''))
  }

  // eslint-disable-next-line no-nested-ternary
  const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}

  // eslint-disable-next-line guard-for-in
  for (const key in obj) {
    result[key] = deepClone(obj[key])
  }

  return result
}